package com.gglu.www.wechatsecurity;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gglu.www.service.impl.webmagic.ArticleServiceImpl;
import com.gglu.www.service.webmagic.ArticleService;
import com.gglu.www.util.EventDispatcher;
import com.gglu.www.util.MessageDispatcher;
import com.gglu.www.util.MessageUtil;
import com.gglu.www.util.WeixinConfigUtil;
import com.gglu.www.util.aes.SignUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;

import static org.apache.commons.httpclient.HttpParser.readLine;
import static org.springframework.util.StreamUtils.BUFFER_SIZE;

/**
 * 杭州新苗网络科技有限公司
 *
 * @author meihf
 * @create 2018/2/4
 * @description
 */
@Controller
@RequestMapping("wechat")
public class WeChatSecurity {

    private Logger logger = LoggerFactory.getLogger(WeChatSecurity.class);

    @Autowired
    ArticleService articleService;

    @Autowired
    ArticleServiceImpl articleService2;

    @RequestMapping(value = "security",method = RequestMethod.GET)
    @ResponseBody
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echostr = request.getParameter("echostr");
        PrintWriter out = response.getWriter();
        // 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
        if (WeixinConfigUtil.checkSignature(signature, timestamp, nonce)) {
            out.print(echostr);
        }
        out.close();
    }

    @RequestMapping(value = "security",method = RequestMethod.POST)
    @ResponseBody
    public void doPost(HttpServletResponse response,HttpServletRequest request){
        try {
            //request 为请求的 HttpServletRequest 参数
            String encrypt_type =request.getParameter("encrypt_type");
            logger.info("公众号发来的消息"+request.getParameterMap().toString());
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();
            String resultMessage = "";
            if (encrypt_type == null || encrypt_type.equals("raw")) { //不用加密
                // 微信加密签名
                String signature = request.getParameter("signature");
                // 时间戳
                String timestamp = request.getParameter("timestamp");
                // 随机数
                String nonce = request.getParameter("nonce");
                if (WeixinConfigUtil.checkSignature(signature, timestamp, nonce)) {
                    Map<String, String> map=MessageUtil.parseXml(request);
                    resultMessage = MessageDispatcher.processMessage(map);
                    out.print(resultMessage);
                } else {
                    out.print("check Error");
                }
            } else {//需走加解密流程
                // 微信加密签名
                String msgSignature = request.getParameter("msg_signature");
                // 时间戳
                String timeStamp = request.getParameter("timestamp");
                // 随机数
                String nonce = request.getParameter("nonce");
                //密文
//                String encryptMsg = readLine(request.getInputStream());
                String encryptMsg = InputStreamTOString(request.getInputStream());

                String data = SignUtil.decryptMsg(msgSignature, timeStamp, nonce, encryptMsg);
                if(data.length() == 0) {
                    data =  "CheckError";
                    out.print(data);
                } else {
                    Map<String, String> map=MessageUtil.parseStrToXml(data);
                    //业务处理方法，返回为XML格式的结果信息
                    String msgType = (String) map.get("MsgType");
                    if(MessageUtil.REQ_MESSAGE_TYPE_EVENT.equals(msgType)){
                        resultMessage = EventDispatcher.processEvent(map); //进入事件处理
                    }else{
                        resultMessage = MessageDispatcher.processMessage(map); //进入消息处理
                    }
                    logger.info("message:"+resultMessage);
                    resultMessage = SignUtil.ecryptMsg(resultMessage, timeStamp, nonce);
                    out.print(resultMessage);
                }
            }
            out.flush();
            out.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String InputStreamTOString(InputStream in) throws Exception{

        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] data = new byte[BUFFER_SIZE];
        int count = -1;
        while((count = in.read(data,0,BUFFER_SIZE)) != -1)
            outStream.write(data, 0, count);

        return new String(outStream.toByteArray(),"UTF-8");
    }

}
